package jacky.lanlan.song.extension.struts.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 标记标注，代表该Class是一个纯POJO的Action，受 {@link POJOActionController} 委托执行业务逻辑。
 * POJO式的Action类不需要实现任何接口或继承任何类，不需要依赖底层的Servlet API，<i><b>甚至不需要 依赖任何 Struts
 * API</b></i>。只需要所声明的执行方法符合以下模式即可： <code><pre style="font-weight:bolder;color:red">
 * &nbsp;@Execution
 * &nbsp;@Form
 * &nbsp;@Input("/foo.jsp")
 *  ...
 *  public String <i>methodName</i>(ValueStack,Map&lt;String,String&gt;) throws Exception
 * </pre></code> <i style="font-size:13px;">
 * <ol>
 * <li>
 * 方法必须标注{@link Execution}，其他标注可按需添加(见本包其他类)，用来完全替代原始Struts的配置文件</li>
 * <li>
 * 其中，Map映射了该次请求产生的 ActionForm 结构，key为属性名，value为属性值</li>
 * <li>
 * 如果Form类型为LazyValidatorForm，则Map里面还会有请求的Parameter键值对</li>
 * <li>
 * 如果执行方法没有 {@link Form} 标注，则Map为一个空Map</li>
 * </ol>
 * </i> <span style="color:red"> POJO Action 和原来的Action一样是Singleton，编程模型并没有改变，所以也必须确保 POJO Action
 * 是线程安全的。 </span>
 * <p>
 * 关于页面导航：<br>
 * <ol>
 * <li>
 * 默认情况下会为每个执行方法(@Execute)创建成功(success)和失败(failure)两个Forward。</li>
 * <li>
 * 可以通过 {@link SuccessTo} 和/或 {@link FailureTo} 标注重载默认设置。</li>
 * <li>
 * 其他名字的 Forward 可以通过{@link Forward} 标注配置。</li>
 * <li>
 * 在指定的 Action 包路径下，可以放置一个名为 view.properties 的配置文件，该配置文件配置了和 其<b>在同一个包下</b>的 {@link POJOAction}
 * 的页面导航。<br>
 * 其中键的格式为：<i>Action 类名 + '.' + 执行方法名 + '.' + Forward名</i><br>
 * 对应的值为页面路径。<br>
 * 比如：
 * 
 * <pre>
 *   &lt;code&gt;
 *   package aaa.bbb;
 *   public class FooAction{
 *     &#064;Execution
 *     public String bar(ValueStack vs,Map&lt;String,String&gt; input){
 *       // ...
 *       return &quot;ok&quot;;
 *     }
 *   }
 *   &lt;/code&gt;
 *   同时，包 aaa.bbb 下的 view.properties 文件：
 *   FooAction.bar.ok = /allAreFine.jsp
 * </pre>
 * 
 * 则 ok 将会被导航至 /allAreFine.jsp。</li>
 * </ol>
 * 以上4种配置 Forward 方式的优先级为:<br>
 * <i>view.properties > SuccessTo/FailureTo > Forward > 默认配置</i>
 * <p>
 * 同时，ValueStack 实现类还实现了ActionContext，如果需要访问底层 Servlet API，可以强制cast为 ActionContext，以获得Servlet
 * API访问权。
 * <p>
 * 最后，Action 可以定义Cancell方法来处理用户取消表单提交的操作：
 * <p>
 * <code style="color:red;"> public String
 * <i>methodName_Cancell</i>(ValueStack,Map&lt;String,String&gt;) throws Exception </code>
 * <p>
 * Cancell方法不需要任何标注，每个Cancell方法对应一个执行方法，<i style="color:red;">它返回的目标页面名称
 * 将在它对应的执行方法所配置的Forward中寻找。</i>
 * <p>
 * 最后，POJO Action 还以一种很优雅的方式支持资源的上传下载问题，详情见{@link Download} 和 {@link Upload} 。
 * <p>
 * 这样一个纯POJO的 Action，只需要mock ValueStack(已提供两个Mock实现： <code>MockValueStack</code> 和
 * <code>DelegateMockValueStack</code>)，不需要依 赖任何环境，即可用JUnit测试，这样可以大大简化基于Struts 1的应用开发。
 * 
 * @author Jacky.Song
 * @see jacky.lanlan.song.extension.struts.POJOActionController
 * @see jacky.lanlan.song.extension.struts.action.ValueStack
 * @see jacky.lanlan.song.extension.struts.action.ActionContext
 * @see jacky.lanlan.song.extension.struts.mock.MockValueStack
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface POJOAction {
	
	/**
	 * POJOAction 在 <code>Spring</code> 中注册的Bean名称。
	 */
	String name() default "";
}